#ifndef LRU_K_CACHE_HPP
#define LRU_K_CACHE_HPP

#include <memory>

#include "./LruCache.hpp"

namespace CachePool
{
    // LRU优化：Lru-k版本。通过继承的方式进行再优化
    // 两种队列：1.历史队列 2.缓存队列
    // 私有成员封装基类指针作为历史队列
    // 直接使用基类作为缓存队列
    // 历史队列k次访问后加入缓存队列
    template <typename Key, typename Value>
    class LruKCache : public LruCache<Key, Value>
    {
    public:
        LruKCache(const size_t capacity, const size_t historyQueueCapacity, const size_t k)
            : LruCache<Key, Value>(capacity), // 调用基类构造
              historyQueue_(std::make_unique<LruCache<Key, size_t>>(historyQueueCapacity)),
              k_(k)
        {
        }

        ~LruKCache() override = default; // 可以的

        void set(const Key &key, const Value value) override
        {
            // 先判断是否存在于缓存队列中，如果存在于则直接覆盖，如果不存在则不直接添加到缓存
            // if (LruCache<Key, Value>::get(key) != "")
            // {
            //     LruCache<Key, Value>::put(key, value);
            // }
            // OPTIMIZE: 在缓存队列，修改缓存队列，不操作历史队列
            if (LruCache<Key, Value>::get(key, value) == true)
            {
                LruCache<Key, Value>::set(key, value);
                return; // 不操作历史队列
            }

            // 如果数据历史访问次数达到上限，则添加入缓存
            // int historyCount = historyList_->get(key); // 默认初始化historyCount为0，不确定吧
            // historyList_->set(key, ++historyCount);
            // OPTIMIZE: 细化，在历史队列历史次数+1，不在历史次数初始化为1
            size_t historyCount{};
            if (this->historyQueue_->get(key, historyCount) == true)
            {
                this->historyQueue_->set(key, ++historyCount);
            }
            else
            {
                this->historyQueue_->set(key, 1);
            }

            if (historyCount >= this->k_)
            {
                // 移除历史访问记录
                this->historyQueue_->del(key);
                // 添加入缓存中
                LruCache<Key, Value>::set(key, value);
            }
        }

        Value get(const Key &key) override
        {
            // 获取该数据访问次数
            // int historyCount = historyList_->get(key);
            // 如果访问到数据，则更新历史访问记录节点值count++
            // historyList_->set(key, ++historyCount);

            // 不判断超过k加入缓存队列逻辑即没有修改操作
            // 用户存取值实际只看得见缓存队列
            // OPTIMIZE: 细化，在历史队列历史次数+1，不在历史次数初始化为1
            size_t historyCount{};
            if (this->historyQueue_->get(key, historyCount) == true)
            {
                this->historyQueue_->set(key, ++historyCount);
            }
            else
            {
                this->historyQueue_->set(key, 1);
            }

            // 从缓存中获取数据，不一定能获取到，因为可能不在缓存中
            return LruCache<Key, Value>::get(key);
        }

    private:
        std::unique_ptr<LruCache<Key, size_t>> historyQueue_; // 访问数据历史记录队列（value为访问次数）
        size_t k_;                                            // 进入缓存队列的评判标准
    };
} // namespace CachePool

#endif // LRU_K_CACHE_HPP